package com.vc.videosdk.utils

import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject
import com.vc.videosdk.xlog.XLogUtil


/**
 * 视频流信息计算工具
 */
object VideoInfoCalculateUtil {

    //===========begin============成员变量记录上一次的值 ===============//
    private var lastPacketsLost = 0
    private var lastPacketsReceived = 0
    private var lastBytesReceived = 0
    private var lastReportTime = 0L
    private var connectStatus = 0;
    private const val TAG = "VideoInfoCalculateUtil_"



    //===========end============成员变量记录上一次的值 ===============//
    fun getRoundTripTime(info: String, listener: VideoInfoListener): Long {
        try {
            val json = getJsonArray(info, "stats")
            val pairMap = HashMap<String?, JSONObject?>()
            val localCandidateMap = HashMap<String, JSONObject>()
            val remoteCandidateMap = HashMap<String, JSONObject>()
            var jsonTransport: JSONObject? = null
            var inbound_video: JSONObject? = null
            var inbound_audio: JSONObject? = null

            for (i in 0 until json!!.size) {
                val jsonObject = JSONObject.parseObject(json[i].toString())
                //处理jsonObject
//                DDLog.d("JSONParse", "jsonObject:$jsonObject")
                val type = jsonObject.getString("type")
                val id = jsonObject.getString("id")

                if (type.equals("transport")) {
                    jsonTransport = jsonObject
                }

                if (type.equals("candidate-pair")) {
                    pairMap[id] = jsonObject
                }
                if (true) {
                    if (type.equals("local-candidate")) {
                        localCandidateMap[id] = jsonObject
                    }

                    if (type.equals("remote-candidate")) {
                        remoteCandidateMap[id] = jsonObject
                    }

                    if (type.equals("inbound-rtp")) {
                        val kind = jsonObject?.getString("kind")
                        if (kind.equals("video")) {
                            inbound_video = jsonObject
                        }
                        if (kind.equals("audio")) {
                            inbound_audio = jsonObject
                        }
                    }
                }
//                DDLog.d("JSONParse", "type: $type, id: $id")
            }
            //网络往返RTT时间----界面展示的网络延迟
            var currentRoundTripTime = 0f
            //选择使用的pair
            val selectedCandidatePairId = jsonTransport?.getString("selectedCandidatePairId")
            //用于获取网络连接类型
            var localCandidateId = ""
            //用于获取网络连接类型
            var remoteCandidateId = ""

            //线性增长丢包数  音频+视频
            var packetsLost = 0
            for (value in pairMap.values) {
                if (value?.getString("id").equals(selectedCandidatePairId)) {
                    currentRoundTripTime = value!!.getFloat("currentRoundTripTime")
                    if (true) {
                        localCandidateId = value.getString("localCandidateId")
                        remoteCandidateId = value.getString("remoteCandidateId")
                    }
                }
            }
            if (true) {
                //本次报道状态的时间戳
                val timestamp = jsonTransport?.getLong("timestampUs")//没有
//                DDLog.d("本次报道状态的时间戳: $timestamp")
                //线性增长接收字节数
                val bytesReceived = jsonTransport?.getInteger("bytesReceived")
                //线性增长接收包数
                val packetsReceived = jsonTransport?.getInteger("packetsReceived") ?: 0

                val framesPerSecond = inbound_video?.getString("framesPerSecond")//每秒帧数 ----界面展示的帧率
                val frameWidth = inbound_video?.getInteger("frameWidth")//视频宽----界面展示的视频宽
                val frameHeight = inbound_video?.getInteger("frameHeight")//视频高----界面展示的视频高

                packetsLost += inbound_audio?.getInteger("packetsLost")!!
                packetsLost += inbound_video?.getInteger("packetsLost")!!
                //计算上次报道到这一次的丢包率---------界面展示百分比丢包率
                var lostRate =
                    ((packetsLost - lastPacketsLost) / ((packetsReceived!! - lastPacketsReceived) + (packetsLost - lastPacketsLost)).toDouble()) * 100
//                DDLog.d("lgz>>>lostRate>>>>packetsLost=${packetsLost},packetsReceived=${packetsReceived},packetsReceived+packetsLost=${packetsReceived+packetsLost}")
//                var lostRate =
//                    (packetsLost / (packetsReceived+packetsLost).toDouble()) * 100
                //记录上一次丢包数
                lastPacketsLost = packetsLost
                //记录上一次接收包数
                lastPacketsReceived = packetsReceived
                //计算每秒接收字节数---------界面展示每秒接收
                var preReceive = 0
                if (lastReportTime > 0) {
                    val diffReceive = (bytesReceived!! - lastBytesReceived).toFloat()
                    val diffTime = (timestamp!! - lastReportTime).toFloat()
                    preReceive = ((diffReceive / diffTime) * 1000000 / 1024).toInt()
                }
                //记录上一次接收字节数
                lastBytesReceived = bytesReceived!!
                //记录上一次报道时间
                if (timestamp != null) {
                    lastReportTime = timestamp
                }
//                DDLog.d("计算每秒接收字节数: $preReceive ")
                //连通类型判断

                var remoteCandidateType = ""
                var localCandidateType = ""
                var localRelatedAddress = ""
                for (value in localCandidateMap.values) {
                    if (value.getString("id").equals(localCandidateId)) {
//                        DDLog.d("local= $value")
                        localCandidateType = value.getString("candidateType")
                        try {
                            localRelatedAddress = value.getString("relatedAddress")
                        } catch (e: Exception) {
                            localRelatedAddress = ""
                        }
                    }
                }
                var remoteTypeIP = ""
                for (value in remoteCandidateMap.values) {
//                    DDLog.d("value= $value")
//                    DDLog.d("remoteCandidateId= $remoteCandidateId")
                    if (value.getString("id").equals(remoteCandidateId)) {
//                        DDLog.d("remote= $value")
                        remoteCandidateType = value.getString("candidateType").toString()
                        remoteTypeIP = value.getString("ip").toString()
                    }
                }
                if (localCandidateType.equals("relay") || remoteCandidateType.equals("relay")) {
                    //网络连通走的中转
                    remoteCandidateType = "中转 $remoteCandidateType"
                    connectStatus = 2
                } else {
                    //网络连通走的P2P
                    remoteCandidateType = "P2P $remoteCandidateType"
                    connectStatus = 1
                }
                //网络连通host就是主机地址，srflx打洞 ,relay中转 网络连通走的P2P
//                when (remoteCandidateType){
//                    "srflx"->{
//                        remoteCandidateType = "P2P $remoteCandidateType"
//                    }
//                    "host"->{
//                        remoteCandidateType = "P2P/局域网 $remoteCandidateType"
//                    }
//                    "relay"->{
//                        remoteCandidateType = "中转 $remoteCandidateType"
//                    }
//                    else ->{
//                        remoteCandidateType = " $remoteCandidateType"
//                    }
//                }
//                val status = "宽高: ${frameWidth}x$frameHeight \n帧率: $framesPerSecond" +
////                        "\n时间戳: $timestamp" +
//                        "\n网络连接: $remoteCandidateId" +
//                        "\nlocalCandidateType: $localCandidateType" +
//                        "\nlocalRelatedAddress: $localRelatedAddress" +
//                        "\n延迟:  ${currentRoundTripTime * 1000} \n每秒: ${preReceive}kb" +
//                        "\n三网IP: ${remoteTypeIP} \n方案:${remoteCandidateType}"+
//                        "\n丢包率: ${lostRate}% \n增长丢包数: $packetsLost "

                listener?.callbackStatus(
                    frameWidth,
                    frameHeight,
                    framesPerSecond,
                    (currentRoundTripTime * 1000),
                    preReceive,
                    lostRate
                )

            }
            return (currentRoundTripTime * 1000).toLong()
        } catch (e: Exception) {
            e.printStackTrace()
            XLogUtil.e("${TAG}getRoundTripTime Exception:" + e.message + ",,,stackTraceToString:" + e.stackTraceToString())
        }
        return 0
    }


    /**
     * 转换成JsonElement
     */
    fun toJsonElement(json: String?): JSONObject? {
        try {
            val jsonObject = JSON.parseObject(json.toString().trim())
            return jsonObject
        } catch (e: Exception) {
            e.printStackTrace()
            XLogUtil.e("${TAG}toJsonElement Exception:" + e.stackTraceToString())
        }
        return null
    }


    /**
     * 获取一个JsonArray
     */
    fun getJsonArray(json: String?, key: String): JSONArray? {
        try {
            val jsonElement = toJsonElement(json)
            return jsonElement?.getJSONArray(key)
        } catch (e: Exception) {
            e.printStackTrace()
            XLogUtil.e("${TAG}getJsonArray Exception:" + e.stackTraceToString())
        }
        return null
    }

    interface VideoInfoListener {
        fun callbackStatus(
            frameWidth: Int?,
            frameHeight: Int?,
            frameRate: String?,
            delay: Float,
            receivePerSecond: Int,
            packetLossRate: Double
        )
    }
}